#include "Property/GUIPropertyDefinition.h"
#include "Control/GUIWindow.h"
#include "Control/GUIWindowManager.h"

namespace YGUI
{
    PropertyDefinitionBase::PropertyDefinitionBase(
        const String& name, 
        const String& help, 
        const String& initVal, bool writeRedraw, bool writeLayout) :
        Property(name, help, initVal),
        m_writeCausesRedraw(writeRedraw),
        m_writeCausesLayout(writeLayout)
    {
    }

    void PropertyDefinitionBase::set(PropertyReceiver* receiver, const String& value)
    {
        if(m_writeCausesLayout)
            static_cast<Window*>(receiver)->notifyChildWindowLayout();
        if(m_writeCausesLayout)
            static_cast<Window*>(receiver)->invalidate();
    }

    PropertyDefinition::PropertyDefinition(const String& name, 
        const String& initVal, bool writeRedraw, bool writeLayout) :
        PropertyDefinitionBase(name, "custom property", initVal, writeRedraw, writeLayout),
        m_userStringName(name + "_auto_property__")
    {
    }

    PropertyDefinition::PropertyDefinition(const String& name, const String& initVal, const String& help, 
        bool writeRedraw, bool writeLayout) :
        PropertyDefinitionBase(name, help, initVal, writeRedraw, writeLayout),
        m_userStringName(name + "_auto_property__")
    {
    }

    String PropertyDefinition::get(const PropertyReceiver* receiver) const
    {
        try
        {
            return static_cast<const Window*>(receiver)->getUserString(m_userStringName);
        }
        catch(...)
        {
            return "";
        }
    }

    void PropertyDefinition::set(PropertyReceiver* receiver, const String& value)
    {
        static_cast<Window*>(receiver)->setUserString(m_userStringName, value);
        PropertyDefinitionBase::set(receiver, value);
    }


    PropertyLinkDefinition::PropertyLinkDefinition(const String& propertyName, 
        const String& widgetNameSuffix, const String& targetPropertyName, 
        const String& initVal, bool writeRedraw, bool writeLayout) : 
        PropertyDefinitionBase(propertyName, "link property", initVal, writeRedraw, writeLayout),
        m_targetPropertyName(targetPropertyName),
        m_widgetNameSuffix(widgetNameSuffix)
    {
    }

    String PropertyLinkDefinition::get(const PropertyReceiver* receiver) const
    {
        const Window* wnd = getTargetWindow(receiver);
        if(wnd)
        {
            return wnd->getProperty(m_targetPropertyName.empty() ? m_name : m_targetPropertyName);
        }
        else
        {
            return "";
        }
    }

    void PropertyLinkDefinition::set(PropertyReceiver* receiver, const String& value)
    {
        Window* wnd = const_cast<Window*>(getTargetWindow(receiver));
        if(wnd)
        {
            wnd->setProperty(m_targetPropertyName.empty() ? m_name : m_targetPropertyName, value);
        }
        PropertyDefinitionBase::set(receiver, value);
    }

    const Window* PropertyLinkDefinition::getTargetWindow(const PropertyReceiver* receiver) const
    {
        if(m_widgetNameSuffix.empty())
            return static_cast<const Window*>(receiver);
        else
        {
            String wndName = static_cast<const Window*>(receiver)->getName() + m_widgetNameSuffix;
            return WindowManager::getSingleton().getWindow(wndName);
        }
    }
};